#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
//验证C/C++程序内存布局
//结论：以系统层面来看，并不是内存，准确叫法是进程地址空间

//运行程序，检测进程，发现子进程被修改之后，对同一个地址空间进行读取，竟然读出来了不同的内容，所以我们C/C++学习时看到的地址绝对不是物理地址，而平时用到的地址叫做虚拟地址/线性地址!
int g_val = 100;
int main()
{
  pid_t id = fork();
  if(id == 0)
  {
    //child process
    int cnt = 5;
    while(1)
    {
      printf("child,pid:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
      sleep(1);
      if(cnt == 0)
      {
        g_val = 200;
        printf("child change g_val:100->200\n");
      }    
        cnt--;
    }
  }else{
    //father
    while(1)
    {
      printf("father,pid:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
      sleep(1);
    }
  }
}











// int un_gval;
// int init_gval=100;
// 
// int main(int argc,char* argv[],char* env[])
// {
//   //代码区地址
//   printf("code addr:%p\n",main);
//   const char* str = "hello Linux!";
//   //字符串常量区
//   printf("read only char addr:%p\n",str);
//   //已初始化全局数据区
//   printf("init global value addr:%p\n",&init_gval);
//   
//   //未初始化全局数据区
//   printf("uninit global value addr:%p\n",&un_gval);
//   //堆区
//   char* heap1 = (char*)malloc(100);
//   char* heap2 = (char*)malloc(100);
//   char* heap3 = (char*)malloc(100);
//   char* heap4 = (char*)malloc(100);
//   char* heap5 = (char*)malloc(100);
//   printf("heap1 addr:%p\n",heap1);
//   printf("heap2 addr:%p\n",heap2);
//   printf("heap3 addr:%p\n",heap3);
//   printf("heap4 addr:%p\n",heap4);
//   printf("heap5 addr:%p\n",heap5);
//   /*堆是向上增长的*/
// 
//   //栈区
//   printf("stack addr:%p\n",&str);
//   printf("stack addr:%p\n",&heap1);
//   printf("stack addr:%p\n",&heap2);
//   printf("stack addr:%p\n",&heap3);
//   printf("stack addr:%p\n",&heap4);
//   printf("stack addr:%p\n",&heap5);
//   /*栈是向下增长的*/
// 
//   //命令行参数与环境变量
//   int i= 0;
//   for(;argv[i];i++)
//   {
//       printf("argv[%d]:%p\n",i, argv[i]);
//   }
// 
//   for(i = 0;env[i];i++)
//   {
//       printf("env[%d]:%p\n",i, env[i]);
//   }
//   return 0;
// }
